package com.zzyl.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.json.JSONUtil;
import com.aliyun.iot20180120.Client;
import com.aliyun.iot20180120.models.*;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.google.gson.JsonObject;
import com.zzyl.base.PageResponse;
import com.zzyl.constant.CacheConstants;
import com.zzyl.dto.DeviceDto;
import com.zzyl.dto.DevicePageQueryDto;
import com.zzyl.entity.Device;
import com.zzyl.enums.BasicEnum;
import com.zzyl.enums.DeviceLocationTypeEnum;
import com.zzyl.enums.DevicePhysicalLocationTypeEnum;
import com.zzyl.exception.BaseException;
import com.zzyl.mapper.DeviceMapper;
import com.zzyl.properties.AliIoTConfigProperties;
import com.zzyl.service.DeviceService;
import com.zzyl.utils.ObjectUtil;
import com.zzyl.vo.*;
import org.assertj.core.util.Lists;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @Description DeviceServiceImpl
 * @Author fy
 * @Date 2025-05-19  16:59
 */
@Service
public class DeviceServiceImpl implements DeviceService {
    @Autowired
    private Client client;
    @Autowired
    private AliIoTConfigProperties aliIoTConfigProperties;

    @Autowired
    private StringRedisTemplate redisTemplate;
    @Autowired
    private DeviceMapper deviceMapper;

    /**
     * 从物联网平台同步产品列表
     */
    @Override
    public void syncProductList() {
        //请求参数
        QueryProductListRequest request = new QueryProductListRequest();
        request.setPageSize(200);
        request.setCurrentPage(1);
        request.setIotInstanceId(aliIoTConfigProperties.getIotInstanceId());

        QueryProductListResponse response = null;
        try {
            response = client.queryProductList(request);
        }catch (Exception e){
            throw new BaseException(BasicEnum.IOT_LIST_PRODUCT_ERROR);
        }
        //检查接口是否调通
        if (!response.getBody().getSuccess()){
            throw  new RuntimeException(response.getBody().getErrorMessage());
        }
        //获取数据，存储到redis中
        List<ProductVo> productVoList = response.getBody()
                .getData()
                .getList()
                .getProductInfo()
                .stream()
                .map(p-> BeanUtil.toBean(p,ProductVo.class))
                .collect(Collectors.toList());
        //存储到redis中
        redisTemplate.opsForValue().set(CacheConstants.ALL_PRODUCT_KEY, JSONUtil.toJsonStr(productVoList));
    }

    /**
     * 查询所有产品列表
     *
     * @return
     */
    @Override
    public List<ProductVo> allProductList() {
        //从缓存中获取数据
        String productListJsonStr = redisTemplate.opsForValue().get(CacheConstants.ALL_PRODUCT_KEY);
        //如果为空，返回空集合
        if (ObjectUtil.isEmpty(productListJsonStr)){
            return Collections.emptyList();
        }
        //转换数据，并返回

        return JSONUtil.toList(productListJsonStr,ProductVo.class);
    }

    /**
     * 注册设备（新增）
     *
     * @param deviceDto 设备注册请求模型
     */
    // @Transactional(rollbackFor = Exception.class) //@Tranzactionl只能于本地数据库事务，不支持回滚外部事务（如阿里云物联网）
    @Override
    public void registerDevice(DeviceDto deviceDto) {

        //检验设备名称是否重复
        Long count = deviceMapper.countByDeviceName(deviceDto.getDeviceName());
        if (count>0){
            throw new BaseException(BasicEnum.DEVICE_NAME_EXIST);
        }
        //iot新增设备
        RegisterDeviceRequest  request = deviceDto.getRegisterDeviceRequest();
        request.setIotInstanceId(aliIoTConfigProperties.getIotInstanceId());
        RegisterDeviceResponse response = null;
        try {
            response = client.registerDevice(request);
        }catch (Exception e){
            throw new BaseException(BasicEnum.IOT_REGISTER_DEVICE_ERROR);
        }
        //接口是否调通
        if (!response.getBody().getSuccess()){
            throw new RuntimeException(response.getBody().getErrorMessage());
        }
        //根据productKey调用阿里云查询产品信息，获取productName
        QueryProductRequest queryProductRequest = new QueryProductRequest();
        queryProductRequest.setIotInstanceId(aliIoTConfigProperties.getIotInstanceId());
        queryProductRequest.setProductKey(deviceDto.getProductKey());
        QueryProductResponse queryProductResponse = null;
        try {
            queryProductResponse = client.queryProduct(queryProductRequest);
        }catch (Exception e){
            throw  new BaseException(BasicEnum.IOT_QUERY_DEVICE_ERROR);
        }
        //接口是否调通
        if (!queryProductResponse.getBody().getSuccess()){
            throw new RuntimeException(queryProductResponse.getBody().getErrorMessage());
        }
        //保存设备
        Device device = BeanUtil.toBean(deviceDto, Device.class);
        device.setIotId(response.getBody().getData().getIotId());
        device.setProductName(queryProductResponse.getBody().getData().getProductName());
        //如果设备绑定的位置是随身设备，则把物理绑定位置设置为-1
        if (device.getLocationType().equals(DeviceLocationTypeEnum.PORTABLE_DEVICE.getOrdinal())){
            device.setPhysicalLocationType(DevicePhysicalLocationTypeEnum.ELDER.getOrdinal());
        }

        deviceMapper.insertSelective(device);
    }

    /**
     * 分页条件查询设备
     * @param devicePageQueryDto
     * @return
     */
    @Override
    public PageResponse<DeviceVo> pageQueryDevice(DevicePageQueryDto devicePageQueryDto) {
        PageHelper.startPage(devicePageQueryDto.getPageNum(),devicePageQueryDto.getPageSize());
        Page<DeviceVo> list = deviceMapper.selectDeviceByPage(devicePageQueryDto);
        return PageResponse.of(list,DeviceVo.class);
    }

    /**
     * 查询设备详细数据
     *
     * @param request
     * @return
     */
    @Override
    public DeviceVo queryDeviceDetail(QueryDeviceDetailRequest request) {
        request.setIotInstanceId(aliIoTConfigProperties.getIotInstanceId());
        System.out.println(request.getIotId());
        QueryDeviceDetailResponse response = null;
        try {
            response = client.queryDeviceDetail(request);
        }catch (Exception e){
            throw new BaseException(BasicEnum.IOT_QUERY_DEVICE_ERROR);
        }
        if (!response.getBody().getSuccess()){
            throw new RuntimeException(response.getBody().getErrorMessage());
        }
        DeviceVo deviceVo = deviceMapper.selectByIotId(response.getBody().getData().getIotId());
        BeanUtil.copyProperties(response.getBody().getData(),deviceVo);
        return deviceVo;
    }

    @Override
    public ThingModelVo queryThingModelPublished(QueryThingModelPublishedRequest queryThingModelPublishedRequest) {
        // 设置 IotInstanceId（从配置中获取）
        queryThingModelPublishedRequest.setIotInstanceId(aliIoTConfigProperties.getIotInstanceId());

        QueryThingModelPublishedResponse response = null;
        try {
            response = client.queryThingModelPublished(queryThingModelPublishedRequest);
        }catch(Exception e){
            throw new BaseException(BasicEnum.IOT_QUERY_THING_MODEL_PUBLISHED_ERROR);
        }
        if (!response.getBody().getSuccess()){
            throw new RuntimeException(response.getBody().getErrorMessage());
        }
        return new ThingModelVo(response.getBody().getData().getThingModelJson());
    }

    /**
     * 查询指定设备的物模型运行状态
     *
     * @param request
     * @return
     */
    @Override
    public DevicePropertystatus queryDevicePropertyStatus(QueryDevicePropertyStatusRequest request) {
        request.setIotInstanceId(aliIoTConfigProperties.getIotInstanceId());
        QueryDevicePropertyStatusResponse response = null;
        try {
            response = client.queryDevicePropertyStatus(request);
        }catch (Exception e){
            throw new BaseException(BasicEnum.IOT_QUERY_DEVICE_PROPERTY_STATUS_ERROR);
        }
        if(!response.getBody().getSuccess()){
            throw new RuntimeException(response.getBody().getErrorMessage());
        }
        // List<PropertyStatusInfo> propertyStatusInfo = response.getBody()
        //         .getData()
        //         .getList()
        //         .getPropertyStatusInfo()
        //         .stream()
        //         .map(item ->BeanUtil.toBean(item,PropertyStatusInfo.class))
        //         .collect(Collectors.toList());
        // PropertyStatusVo result = new PropertyStatusVo();
        //
        // result.setPropertyStatusInfo(propertyStatusInfo);
        DevicePropertystatus result = new DevicePropertystatus();
        result.setList(response.getBody().getData().getList());
        return result;
    }

    @Override
    public void updateDevice(DeviceDto deviceDto) {
        //检验数据库是否存在设备
        Device dbDevice = deviceMapper.selectByPrimaryKey(deviceDto.getId());
        if (ObjectUtil.isEmpty(dbDevice)){
            throw new BaseException(BasicEnum.DEVICE_NOT_EXIST);
        }
        // 保存位置
        Device device = BeanUtil.toBean(deviceDto,Device.class);
        //如果是随身设备，物理位置设为-1
        if (device.getLocationType().equals(DeviceLocationTypeEnum.PORTABLE_DEVICE.getOrdinal())){
            device.setPhysicalLocationType(DeviceLocationTypeEnum.PORTABLE_DEVICE.getOrdinal());
        }
        deviceMapper.updateByPrimaryKeySelective(device);
        BatchUpdateDeviceNicknameRequest request = new BatchUpdateDeviceNicknameRequest();
        request.setIotInstanceId(aliIoTConfigProperties.getIotInstanceId());
        BatchUpdateDeviceNicknameRequest.BatchUpdateDeviceNicknameRequestDeviceNicknameInfo nicknameInfo = BeanUtil.toBean(deviceDto,BatchUpdateDeviceNicknameRequest.BatchUpdateDeviceNicknameRequestDeviceNicknameInfo.class);
        request.setDeviceNicknameInfo(Lists.newArrayList(nicknameInfo));
        BatchUpdateDeviceNicknameResponse response = null;
        try {
            response = client.batchUpdateDeviceNickname(request);
        }catch(Exception e){
            throw new BaseException(BasicEnum.IOT_BATCH_UPDATE_DEVICE_ERROR);
        }
        if (!response.getBody().getSuccess()){
            throw new RuntimeException(response.getBody().getErrorMessage());
        }

    }

    /**
     * 删除设备
     * @param request
     */
    @Override
    public void deleteDevice(DeleteDeviceRequest request) {
        //删除数据库设备信息
        deviceMapper.deleteByIotId(request.getIotId());
        request.setIotInstanceId(aliIoTConfigProperties.getIotInstanceId());
        DeleteDeviceResponse response = null;
        try {
            response = client.deleteDevice(request);
        }catch (Exception e){
            throw  new BaseException(BasicEnum.IOT_DELETE_DEVICE_ERROR);
        }
        if (!response.getBody().getSuccess()){
            throw new RuntimeException(response.getBody().getErrorMessage());
        }

    }
}
